package com.example.onlineanswer.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.onlineanswer.common.annotation.RequiresLogin;
import com.example.onlineanswer.common.api.CommonResult;
import com.example.onlineanswer.common.util.JwtUtil;
import com.example.onlineanswer.model.dto.RankingDTO;
import com.example.onlineanswer.model.entity.Contest;
import com.example.onlineanswer.model.entity.Question;
import com.example.onlineanswer.model.vo.ContestAnswerVO;
import com.example.onlineanswer.model.vo.ContestDetailVO;
import com.example.onlineanswer.model.vo.ContestVO;
import com.example.onlineanswer.model.vo.RankingVO;
import com.example.onlineanswer.service.ContestRankingService;
import com.example.onlineanswer.service.ContestService;
import com.example.onlineanswer.service.QuestionService;
import com.example.onlineanswer.model.vo.ContestAnswerVO;
import com.example.onlineanswer.model.vo.ContestVO;
import com.example.onlineanswer.model.vo.QuestionVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;
import java.util.HashMap;
import java.util.Map;

/**
 * 竞赛控制器
 */
@Api(tags = "竞赛接口")
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
@Slf4j
public class ContestController {

    private final ContestService contestService;
    private final QuestionService questionService;
    private final ContestRankingService contestRankingService;
    private final JwtUtil jwtUtil;

    /**
     * 分页查询竞赛列表
     *
     * @param current      当前页
     * @param size         每页大小
     * @param status       状态（可选）
     * @param excludeStatus 排除的状态（可选）
     * @param keyword      关键词（可选）
     * @param creatorId    创建者ID（可选）
     * @return 竞赛列表
     */
    @GetMapping("/contests")
    public CommonResult<IPage<ContestVO>> getContestList(
            @RequestParam(defaultValue = "1") long current,
            @RequestParam(defaultValue = "10") long size,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) Integer excludeStatus,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Long creatorId) {
        Page<ContestVO> page = new Page<>(current, size);
        IPage<ContestVO> result = contestService.pageContestList(page, status, excludeStatus, keyword, creatorId);
        return CommonResult.success(result);
    }

    /**
     * 获取竞赛详情
     *
     * @param id 竞赛ID
     * @return 竞赛详情
     */
    @GetMapping("/contests/{id}")
    public CommonResult<ContestVO> getContestDetail(@PathVariable Long id) {
        ContestVO contest = contestService.getContestDetailById(id);
        if (contest == null) {
            return CommonResult.failed("竞赛不存在");
        }
        return CommonResult.success(contest);
    }

    /**
     * 创建竞赛
     *
     * @param contest 竞赛信息
     * @return 竞赛ID
     */
    @PostMapping("/contest/create")
    @RequiresLogin
    public CommonResult<Long> createContest(@RequestBody Contest contest) {
        Long id = contestService.createContest(contest);
        return CommonResult.success(id);
    }

    /**
     * 更新竞赛
     *
     * @param id      竞赛ID
     * @param contest 竞赛信息
     * @return 是否成功
     */
    @PutMapping("/contests/{id}")
    @RequiresLogin
    public CommonResult<Boolean> updateContest(@PathVariable Long id, @RequestBody Contest contest) {
        contest.setId(id);
        boolean success = contestService.updateContest(contest);
        return success ? CommonResult.success(true) : CommonResult.failed("更新失败");
    }

    /**
     * 审核竞赛
     *
     * @param id        竞赛ID
     * @param status    审核状态 (1: 通过, 2: 拒绝)
     * @param reviewerId 审核人ID
     * @return 是否成功
     */
    @PutMapping("/contests/{id}/review")
    @RequiresLogin
    public CommonResult<Boolean> reviewContest(
            @PathVariable Long id,
            @RequestParam Integer status,
            @RequestParam Long reviewerId) {
        if (status != 1 && status != 2) {
            return CommonResult.failed("无效的审核状态");
        }
        boolean success = contestService.reviewContest(id, status, reviewerId);
        return success ? CommonResult.success(true) : CommonResult.failed("审核失败");
    }

    /**
     * 删除竞赛
     *
     * @param id 竞赛ID
     * @return 是否成功
     */
    @DeleteMapping("/contests/{id}")
    @RequiresLogin
    public CommonResult<Boolean> deleteContest(@PathVariable Long id) {
        boolean success = contestService.deleteContest(id);
        return success ? CommonResult.success(true) : CommonResult.failed("删除失败");
    }

    /**
     * 开始竞赛
     *
     * @param id 竞赛ID
     * @return 是否成功
     */
    @PutMapping("/contests/{id}/start")
    @RequiresLogin
    public CommonResult<Boolean> startContest(@PathVariable Long id) {
        boolean success = contestService.startContest(id);
        return success ? CommonResult.success(true) : CommonResult.failed("开始失败");
    }

    /**
     * 结束竞赛
     *
     * @param id 竞赛ID
     * @return 是否成功
     */
    @PutMapping("/contests/{id}/end")
    @RequiresLogin
    public CommonResult<Boolean> endContest(@PathVariable Long id) {
        boolean success = contestService.endContest(id);
        return success ? CommonResult.success(true) : CommonResult.failed("结束失败");
    }
    
    /**
     * 获取竞赛答题统计
     *
     * @param contestId 竞赛ID
     * @return 竞赛答题统计
     */
    @GetMapping("/contests/{contestId}/statistics")
    public CommonResult<ContestAnswerVO> getContestAnswerStatistics(@PathVariable Long contestId) {
        ContestAnswerVO statistics = contestService.getContestAnswerStatistics(contestId);
        if (statistics == null) {
            return CommonResult.failed("竞赛不存在");
        }
        return CommonResult.success(statistics);
    }
    
    /**
     * 获取竞赛排名
     *
     * @param contestId 竞赛ID
     * @param page      当前页
     * @param size      每页大小
     * @param token     身份验证令牌
     * @return 竞赛排名
     */
    @GetMapping("/contests/{contestId}/ranking")
    public CommonResult<?> getContestRanking(
            @PathVariable Long contestId,
            @RequestParam(required = false, defaultValue = "1") Integer page,
            @RequestParam(required = false, defaultValue = "10") Integer size,
            @RequestHeader(value = "Authorization", required = false) String token) {
        
        log.info("获取竞赛排名 - 竞赛ID: {}, 页码: {}, 每页大小: {}", contestId, page, size);
        
        try {
            // 验证竞赛是否存在
            Contest contest = contestService.getById(contestId);
            if (contest == null) {
                return CommonResult.failed("竞赛不存在");
            }
            
            // 计算排名开始和结束索引
            int start = (page - 1) * size;
            int end = start + size - 1;
            
            // 获取排名列表
            List<RankingDTO> rankingList = contestRankingService.getRankingList(contestId, start, end);
            
            // 获取总参与人数
            Long totalParticipants = contestRankingService.getContestParticipantsCount(contestId);
            
            // 获取当前用户排名（如果已登录）
            Map<String, Object> personalRanking = null;
            
            if (token != null && !token.isEmpty()) {
                try {
                    Long userId = jwtUtil.getUserIdFromToken(token.replace("Bearer ", ""));
                    if (userId != null) {
                        RankingDTO userRanking = contestRankingService.getUserRanking(contestId, userId);
                        if (userRanking != null) {
                            Long userRank = contestRankingService.getUserRank(contestId, userId);
                            if (userRank != null) {
                                // 创建个人排名视图对象
                                personalRanking = new HashMap<>();
                                personalRanking.put("userId", userRanking.getUserId());
                                personalRanking.put("nickname", userRanking.getNickname());
                                personalRanking.put("avatar", userRanking.getUserAvatar());
                                personalRanking.put("totalScore", userRanking.getScore());
                                personalRanking.put("rank", userRank.intValue());
                                personalRanking.put("correctCount", userRanking.getCorrectCount());
                                personalRanking.put("avgTime", userRanking.getTotalTime());
                                personalRanking.put("isCurrentUser", true);
                            }
                        }
                    }
                } catch (Exception e) {
                    log.warn("获取用户排名异常: {}", e.getMessage());
                    // 不影响整体返回结果，继续执行
                }
            }
            
            // 构造分页对象
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("records", rankingList);
            resultMap.put("total", totalParticipants);
            resultMap.put("pages", (int) Math.ceil((double) totalParticipants / size));
            resultMap.put("size", size);
            resultMap.put("current", page);
            resultMap.put("personal", personalRanking);
            
            return CommonResult.success(resultMap);
        } catch (Exception e) {
            log.error("获取竞赛排名异常: {}", e.getMessage(), e);
            return CommonResult.failed("获取排名数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取竞赛题目列表
     *
     * @param contestId 竞赛ID
     * @return 题目列表
     */
    @GetMapping("/contests/{contestId}/questions")
    public CommonResult<List<QuestionVO>> getContestQuestions(@PathVariable Long contestId) {
        List<Question> questions = questionService.getQuestionsByContestId(contestId);
        
        // 转换为VO对象
        List<QuestionVO> result = questions.stream()
            .map(question -> {
                QuestionVO vo = new QuestionVO();
                // 复制基本属性
                vo.setId(question.getId());
                vo.setContestId(question.getContestId());
                vo.setTypeId(question.getTypeId());
                vo.setContent(question.getContent());
                vo.setDifficulty(question.getDifficulty());
                vo.setScore(question.getScore());
                vo.setTimeLimit(question.getTimeLimit());
                vo.setOrderNum(question.getOrderNum());
                vo.setStatus(question.getStatus());
                // 不复制敏感信息，如正确答案等
                return vo;
            })
            .collect(Collectors.toList());
        
        return CommonResult.success(result);
    }
    
    /**
     * 检查用户是否已加入竞赛
     *
     * @param contestId 竞赛ID
     * @return 是否已加入
     */
    @GetMapping("/contests/{contestId}/joined")
    @RequiresLogin
    public CommonResult<Boolean> checkUserJoined(@PathVariable Long contestId, @RequestHeader("Authorization") String token) {
        try {
            // 从token获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token.replace("Bearer ", ""));
            if (userId == null) {
                return CommonResult.failed("无法获取用户信息");
            }
            
            // 检查用户是否已参与竞赛
            boolean joined = contestService.isUserJoined(contestId, userId);
            return CommonResult.success(joined);
        } catch (Exception e) {
            log.error("检查用户是否加入竞赛异常: {}", e.getMessage(), e);
            return CommonResult.failed("检查失败: " + e.getMessage());
        }
    }
    
    /**
     * 用户参与竞赛
     *
     * @param contestId 竞赛ID
     * @return 是否成功
     */
    @PostMapping("/contests/{contestId}/join")
    @RequiresLogin
    public CommonResult<Boolean> joinContest(@PathVariable Long contestId, @RequestHeader("Authorization") String token) {
        try {
            // 从token获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token.replace("Bearer ", ""));
            if (userId == null) {
                return CommonResult.failed("无法获取用户信息");
            }
            
            // 参与竞赛
            boolean result = contestService.joinContest(contestId, userId);
            return result ? CommonResult.success(true) : CommonResult.failed("参与竞赛失败");
        } catch (Exception e) {
            log.error("参与竞赛异常: {}", e.getMessage(), e);
            return CommonResult.failed("参与失败: " + e.getMessage());
        }
    }
} 